package org.goobs.misc;

import java.util.HashSet;
import java.util.Set;

import org.goobs.utils.Util;

public class CFGRule <E> {

	private E parent;
	private E[] children;
	
	public CFGRule(E parent, E[] children){
		this.parent = parent;
		this.children = children;
	}
	
	public E getParent(){
		return parent;
	}
	
	public E[] getChildren(){
		return children;
	}
	
	public int numChildren(){
		return children.length;
	}
	
	public boolean isSatisfied(String input){
		for(E child : children){
			if(child.equals(input)){
				return true;
			}
		}
		return false;
	}
	
	private static boolean isDone(int[] breaks, int len){
		int max = Integer.MIN_VALUE;
		for(int i=0; i<breaks.length; i++){
			if(breaks[i] <= max){
				System.out.println(max);
				return true;
			}
			max = breaks[i];
		}
		if(breaks[breaks.length-1] >= len){
			return true;
		}
		return false;
	}
	
	private static void increment(int[] breaks, int len){		
		for(int i=breaks.length-1; i>=0; i--){
			breaks[i] += 1;
			for(int j=i+1; j<breaks.length; j++){
				breaks[j] = breaks[j-1] + 1;
			}
			if(breaks[breaks.length-1] < len){
				return;
			}
			
		}
	}
	
	private static String[] split(String input, int[] breaks){
		String[] parts = new String[breaks.length+1];
		int start = 0;
		int marker = 0;
		for(int i=0; i<breaks.length; i++){
			marker = breaks[i];
			parts[i] = input.substring(start, marker);
			start = marker;
		}
		parts[parts.length-1] = input.substring(marker);
		return parts;
	}
	
	public Set <String[]> split(String input){
		Set <String[]> rtn = new HashSet <String[]> ();
		int len = input.length();
		if(len < 1){
			return rtn;
		}
		int[] breaks = new int[children.length-1];
		if(breaks.length == 0){
			rtn.add(new String[]{input.substring(0)});
			return rtn;
		}
		for(int i=0; i<breaks.length; i++){
			breaks[i] = i+1; 
		};
		
		while(!isDone(breaks, len)){
			rtn.add( split(input, breaks) );
			increment(breaks, len);
		}
		return rtn;
	}
	
	
	public static void main(String[] args){
		
//		int[] breaks = {1, 2};
//		int len=3;
//		while(!isDone(breaks,len)){
//			System.out.print("[ ");
//			for(int i : breaks){
//				System.out.print(i + " " );
//			}
//			System.out.println("]");
//			increment(breaks, len);
//		}
		
		CFGRule r = new CFGRule<String>("S", new String[]{"S", "+", "T"});
		Set <String[]> s = r.split("1+1");
		for(String[] str : s){
			System.out.println(Util.arrayString(str));
		}
	}
	
}
